#include "precompiled.h"
#include "Scenery.h"
#include "Core.h"
#include "Geometry_Pool.h"
#include "Model.h"
#include "RenderManager.h"
#include "Camera_Alt.h"
#include "HealthComponent.h"

unsigned int id_count = 0;

float FLASH_DECAY = 1.8f;

Scenery::Scenery(void)
{
	isStatic=false;
	ref_model = 0;
	create_name();

	rticket.shadargs = 0;
	flashable=false;

	health.Initialize( 100, 100 );
}

Scenery::Scenery( std::string model_key, bool IsStatic ){
	isStatic = IsStatic;

	// Get the model from the pool.
	ref_model = gs_geompool->get_modelValue(model_key);

	// Let us know if we were unable to get the model.
	if( ref_model == 0 )
		printf("Scenery unable to retrieve model with key: %s\n",model_key);

	initial_transform._position = glm::vec4(0);
	initial_transform._rotation = glm::vec3(0.0000001);
	initial_transform._scale = glm::vec3(1);

	rticket.bundle.modelKey = model_key;
	rticket.bundle.materialKey = "";
	rticket.bundle.transform = &initial_transform;
	rticket.shadargs = 0;

	doDraw=true;
	doDraw_life=true;

	flash=0.0f;
	flashable=false;

	create_name();

	health.Initialize( 100, 100 );
	death.Initialize( 1.0f );
}

Scenery::~Scenery(void)
{
}

void Scenery::create_name(){
	name = "scenery_" + id_count;
	id_count++;
}

glm::vec3 Scenery::Get_Extents( ){
	glm::vec3 extents = ref_model->Get_Max() / 2.0f;

	/*extents += glm::vec3(transform._position.x,transform._position.y,transform._position.z);

	extents = glm::rotate(extents, transform._rotation.x, glm::vec3(1,0,0));
	extents = glm::rotate(extents, transform._rotation.y, glm::vec3(0,1,0));
	extents = glm::rotate(extents, transform._rotation.z, glm::vec3(0,0,1));

	extents *= transform._scale;*/

	return extents;
}

std::string Scenery::GetName(){
	return name;
}


void Scenery::Initial_Position( glm::vec4 pos ){
	initial_transform._position= pos;
}
void Scenery::Initial_Translate( glm::vec3 translation ){
	initial_transform._position += glm::vec4( translation.x, translation.y, translation.y, 0);
}
void Scenery::Initial_Scale( glm::vec3 scale ){
	initial_transform._scale = scale;
}
void Scenery::Initial_Rotate( glm::vec3 rotate ){
	initial_transform._rotation = rotate;
}

void Scenery::Set_Position( glm::vec4 pos ){
	transform._position=pos;
}
void Scenery::SetWorldMatrix( glm::mat4 &arg_world ){
	transform._model = arg_world;
}


float Scenery::healthAmount(){
	return health.HealthPercentage();
}
bool Scenery::isDead(){
	return (health.HealthPercentage() == 0) ? true : false;
}
void Scenery::lowerHealth( int amount ){
	health.LowerHealth( amount );
}

void Scenery::doDeath( ){
	if( !death.doingDeath()  )
		death.orderDeath();
}
bool Scenery::didDeath(){
	return death.didDeath();
}

void Scenery::form_model_transform(){
	world = glm::translate(glm::mat4(1), 
		glm::vec3(initial_transform._position) + initial_transform._translation );


	world = glm::rotate(world, initial_transform._rotation.x, glm::vec3(1,0,0));
	world = glm::rotate(world, initial_transform._rotation.y, glm::vec3(0,1,0));
	world = glm::rotate(world, initial_transform._rotation.z, glm::vec3(0,0,1));

	world = glm::scale(world, initial_transform._scale); 

	initial_transform._model = world;
}

void Scenery::setDoFlash(){
	if( !flashable )
		return;

	if( rticket.shadargs == 0)
		rticket.shadargs = new ShaderArguments();
	flash=1.0f;
}

void Scenery::Update( GLdouble time ){
	death.Update(time);

	if( death.didDeath() )
		doDraw_life=false;

	if( isStatic )
		form_model_transform();

	// Update our flash amount.
	if( flash > 0.0f ){
		flash = (flash - time < 0.0f) ? 0.0f : flash - time*FLASH_DECAY;

		if( rticket.shadargs == 0 ){
			rticket.shadargs = new ShaderArguments();
			rticket.shadargs->flash = flash;
			//printf("flash amt: %f\n",flash);
		}
	}
}

void Scenery::Draw( glm::mat4 &projview, Camera_Alt const * cam  ){

	if( !doDraw || !doDraw_life )
		return;

	rticket.ref_point_vertexBuffer = 0;
	if( isStatic ){
		rticket.bundle.transform = &initial_transform;
		rticket.distance = cam->getDistanceFromCamera( 
			glm::vec3(  initial_transform._position.x,
						initial_transform._position.y,
						initial_transform._position.z ));
	}
	else{
		rticket.bundle.transform = &transform;
		rticket.distance = cam->getDistanceFromCamera( 
			glm::vec3(  transform._position.x,
						transform._position.y,
						transform._position.z ));
	}


	RendererManager::accept_renderTicket( rticket );
}